<template>
  <div class="write-container t-form-theme-wrap">
    <div
      v-cloak
      v-if="writeStatus == 0"
    >
      <!--			无法填写-->
      <el-result
        class="result-wrapper"
        :title="writeNotStartPrompt"
        icon="error"
      >
        <template #icon>
            <svg t="1747289207983" class="icon" viewBox="0 0 1024 1024" version="1.1" xmlns="http://www.w3.org/2000/svg" p-id="41913" width="48" height="48"><path d="M798.72 942.08H225.28A122.88 122.88 0 0 1 102.4 819.2V163.84a40.96 40.96 0 0 1 40.96-40.96h573.44a40.96 40.96 0 0 1 40.96 40.96v491.52h163.84v163.84a122.88 122.88 0 0 1-122.88 122.88z" fill="#DDE5FC" p-id="41914" data-spm-anchor-id="a313x.search_index.0.i16.4b1f3a8156SzGF" class="selected"></path><path d="M757.76 737.28v81.92a40.96 40.96 0 1 0 81.92 0v-81.92zM266.24 327.68v81.92h327.68v-81.92zM266.24 491.52v81.92h327.68v-81.92zM266.24 655.36v81.92h204.8v-81.92z" fill="#AFC2FA" p-id="41915"></path><path d="M757.76 375.45984A170.67008 170.67008 0 1 1 928.41984 204.8 170.65984 170.65984 0 0 1 757.76 375.45984z" fill="#9e9ef1" p-id="41916" data-spm-anchor-id="a313x.search_index.0.i10.4b1f3a8156SzGF" class="selected"></path><path d="M757.76 180.66432l-48.27136-48.2816-24.14592 24.14592 48.2816 48.26112-48.2816 48.27136 24.14592 24.14592 48.26112-48.2816 48.27136 48.2816 24.14592-24.14592L781.88544 204.8l48.2816-48.27136-24.14592-24.14592z" fill="#FFFFFF" p-id="41917"></path></svg>
        </template>
      </el-result>
    </div>
    <!--    白名单-->
    <div
      v-cloak
      v-if="writeStatus == 3"
    >
      <form-enter-check
        :form-key="formKey"
        :setting="userFormSetting"
        @enter="handleCheckEnter"
      />
    </div>
    <div
      v-if="writeStatus == 1"
      class="form-container h100"
    >
      <biz-project-form
        v-if="formConfig.formKey"
        ref="bizProjectFormRef"
        :form-config="formConfig"
        @submit="submitForm"
        @completed="handleFormLoadCompleted"
        @cover="handleShowFormCover"
      />
      <FormQrcode />
      <!--    商品支付-->
      <goods-pay
        ref="goodsPayRef"
        @pay-success="handlePaymentSuccess"
      />
    </div>
    <div
      v-cloak
      v-if="writeStatus == 2"
      class="title-icon-view"
    >
      <SubmitResult
        v-if="writeStatus == 2"
        :form-key="formKey"
        :form-data="submitFormModelData"
        :result-data="submitResult"
        :setting-config="userFormSetting"
      />
    </div>
    <Transition name="fade">
      <form-cover
        :form-theme-config="themeConfig"
        v-if="showCover"
        @close="showCover = false"
      />
    </Transition>
  </div>
</template>

<script setup lang="ts" name="WriteView">
import { defineAsyncComponent, onBeforeMount, provide, Ref, ref } from "vue";
import { useRoute, useRouter } from "vue-router";
import { useFormWx } from "@/views/form/write/hooks/useFormWxHook";
import { useFormExpand } from "@/views/form/write/hooks/useFormExpandHook";
import {
  createFormResultRequest,
  publicCreateFormResultRequest,
  SubmitFormData,
  viewFormResultRequest
} from "@/api/project/data";
import { getPublicSettingsRequest, getWriteSettingStatusRequest } from "@/api/project/setting";
import {
  getLastFormSubmitRes,
  getTempFormData,
  removeFormData,
  removeTempFormData,
  saveLastFormSubmitRes,
  saveTempFormData
} from "@/views/formgen/utils/db";
import { checkWriteCountCap, saveWriteCount } from "@/views/form/write/hooks/DeviceWriteCount";
import { getFaceIdentifyInfo, getFaceIdentifyUrl } from "@/api/project/form";
import BizProjectForm from "@/views/formgen/components/BizProjectForm/index.vue";
import {
  SHOW_HEADER_USER_INFO_KEY,
  SHOW_LANG_SWITCH_KEY,
  USER_FORM_STATE_KEY
} from "@/views/formgen/components/GenerateForm/types/constants";
import { FormPublicSetting, FormThemeType } from "@/views/formgen/components/GenerateForm/types/form";
import { NextLoading } from "@/utils/loading";
import { useUserForm } from "@/views/formgen/components/GenerateForm/hooks/useUserForm";
import { getFormLogicData } from "@/views/formgen/components/BizProjectForm/FormLogic";

const FormCover = defineAsyncComponent(() => import("./component/FormCover.vue"));
const FormEnterCheck = defineAsyncComponent(() => import("./component/FormEnterCheck.vue"));
const FormQrcode = defineAsyncComponent(() => import("./component/FormQrcode.vue"));
const SubmitResult = defineAsyncComponent(() => import("./component/SubmitResult.vue"));
const GoodsPay = defineAsyncComponent(() => import("./component/GoodsPay.vue"));

const props = defineProps({
  // 1：公开填写 2：指定成员填写 3. 测评填写
  writeType: {
    type: Number,
    default: 1
  },
  // 外部传入
  formKey: {
    type: String,
    default: ""
  },
  // 测评时候评价用户的 Key
  reviewerKey: {
    type: String,
    default: ""
  }
});

const formKey = ref<string>(props.formKey);
const formConfig = ref<any>({
  formKey: "",
  preview: false,
  showBtns: true
});
// 0: 无法填写 1: 可以填写 2: 已填写 3. 密码填写
const writeStatus = ref<number>(1);
const writeNotStartPrompt = ref<string>("");
const userFormSetting = ref<FormPublicSetting | undefined>(undefined);

const submitResult = ref<any>({
  // 数据Id
  dataId: "",
  // 随机编号
  randomNumberText: "",
  // 考试成绩
  examScoreText: ""
});

const router = useRouter();
const route = useRoute();

const { wxUserInfo, handleSettingWxConfig, checkWxWriteSetting, getWxUserInfo } = useFormWx;

const userFormStore = useUserForm();
const { extractInfo, submitLoading, setReviewerKey, currentPageConfig } = userFormStore;

provide(USER_FORM_STATE_KEY, userFormStore);

onBeforeMount(async () => {
  NextLoading.start();
  if (props.formKey) {
    formKey.value = props.formKey;
  } else {
    formKey.value = (route.query["key"] || route.params["key"]) as string;
  }
  // 人脸识别回调
  let callbackRes: any = await handleCallBack();
  if (callbackRes.data) {
    return;
  }
  getWxUserInfo();
  // 检查是否能进入填写
  const statusRes: any = await queryProjectSettingStatus();
  if (!statusRes) {
    return;
  }
  let settingRes = await queryProjectSetting();
  // 查询相关设置 检查是否能打开等
  handleSettingWxConfig(settingRes.data);
  viewFormResultRequest(formKey.value).then(() => {});
  setReviewerKey(props.reviewerKey);
});

/**
 * 检查是否能进入
 * 返回false表示无法进入
 */
const queryProjectSettingStatus = async () => {
  // 是否能进入填写
  const res = await getWriteSettingStatusRequest({
    formKey: formKey.value,
    type: props.writeType,
    cl: route.query.cl,
    uk: route.query.uk,
    wxOpenId: wxUserInfo.value?.openid || ""
  });
  if (res.msg) {
    writeNotStartPrompt.value = res.msg;
    writeStatus.value = 0;
    return false;
  }
  return true;
};

const queryProjectSetting = async () => {
  // 填写设置
  let res = await getPublicSettingsRequest(formKey.value);
  formConfig.value.formKey = formKey.value;
  if (res.data) {
    userFormSetting.value = res.data;
    formConfig.value.setting = res.data;
    checkShowFormSubmitContent(res.data);
    // 设备填写次数校验 检测校验时机是否正确
    checkDeviceWriteLimit(formConfig.value.setting?.writeCheckOccasion !== "1");
    // 检查微信的设置比如仅微信打开 记录授权等
    checkWxWriteSetting(res.data);
    // 开启了密码填写
    if (res.data && (res.data.passwordWriteStatus || res.data.enableWhiteList)) {
      writeStatus.value = 3;
    }
  }
  return res;
};

/**
 * 已填写查看
 */
const checkShowFormSubmitContent = (setting: any) => {
  // 如果有再次填写的参数 说明是通过再次填写的按钮跳转过来的 则忽略缓存
  if (route.query.reWrite) {
    // 移除这个参数 避免刷新还是认为是通过再次填写按钮过来的
    let newQuery = JSON.parse(JSON.stringify(route.query));
    delete newQuery.reWrite;
    router.replace({ query: newQuery });
    return;
  }
  // 开启了查看并且有缓存提交的
  const submitRes = getLastFormSubmitRes(formKey.value);
  if (setting.showSubmitContentBtn && submitRes) {
    writeStatus.value = 2;
    try {
      submitResult.value = JSON.parse(submitRes);
    } catch (e) {
      // 兼容历史版本 1.5版本以前的存储的是id
      submitResult.value.dataId = submitRes;
    }
  }
};

/**
 * 检查设备填写次数 是否校验1
 * 返回true 表示校验失败 次数已满
 */
const checkDeviceWriteLimit = (isCheck?: boolean) => {
  if (!isCheck) {
    return;
  }
  if (userFormSetting?.value?.deviceWriteCountLimitStatus) {
    const flag = checkWriteCountCap(formKey.value, userFormSetting?.value?.deviceWriteCountLimit);
    if (flag) {
      writeNotStartPrompt.value = userFormSetting.value.deviceWriteCountLimitText || "";
      writeStatus.value = 0;
    }
    return flag;
  }
};

const goodsPayRef = ref<any>(null);

// Handle form load completed
const handleFormLoadCompleted = () => {
  NextLoading.done(0);
};

const themeConfig = ref<Ref<FormThemeType> | null>(null);

const showCover = ref(false);

const handleShowFormCover = (theme: FormThemeType) => {
  themeConfig.value = theme;
  showCover.value = true;
};

// Handle payment success
const handlePaymentSuccess = (resData: any, formModel: any) => {
  handleSubmitSuccess(resData || {}, formModel);
};

const bizProjectFormRef = ref<any>(null);

// 请求的表单数据
const submitFormModelData = ref<Record<string, any>>();

// Handle form submission
const submitForm = async (submitFormData: SubmitFormData) => {
  try {
    // 设备填写次数校验 检测校验时机是否正确
    if (checkDeviceWriteLimit(formConfig.value.setting?.writeCheckOccasion === "1")) {
      return;
    }
    submitFormData.wxUserInfo = wxUserInfo.value;
    submitFormData.wxOpenId = wxUserInfo.value ? wxUserInfo.value.openid : "";
    submitFormData.formKey = formKey.value;
    submitFormData.otherParam = extractInfo;
    submitFormData.extValue = useFormExpand().getExtValue();
    const beforeCheck = await handleSubmitBefore(submitFormData);
    if (!beforeCheck) {
      return;
    }
    let res = null;
    if (props.writeType === 1) {
      res = await publicCreateFormResultRequest(submitFormData);
    } else {
      res = await createFormResultRequest(submitFormData);
    }
    handleSubmitSuccess(res.data, submitFormData.originalData);
  } catch (e) {
    console.log(e);
  } finally {
    submitLoading.value = false;
  }
};

// Handle submit success
const handleSubmitSuccess = (resData: any, submitData: any = {}) => {
  submitFormModelData.value = submitData;
  submitResult.value = resData;
  // Remove temporary cached data
  removeFormData(formKey.value);
  // Save write count if device write count limit is enabled
  saveWriteCount(formKey.value);
  // 保存最后一次提交返回结果 用于查看提交数据回显
  saveLastFormSubmitRes(resData, formKey.value);
  writeStatus.value = 2;
  console.log(submitData);
};

// Handle submit before (e.g., payment, face verification)
const handleSubmitBefore = async (submitFormData: any) => {
  // 避免没有显示的商品默认也参与计算
  const logicShowData = getFormLogicData({ ...submitFormData.originalData }, currentPageConfig.value?.logicRuleMap || {});

  if (goodsPayRef.value.openPay({ ...submitFormData, originalData: logicShowData }, formKey.value)) {
    return false;
  }

  let isFaceCheck = false;
  Object.keys(submitFormData.originalData).forEach(key => {
    if (key.includes("face_identify")) {
      isFaceCheck = true;
    }
  });

  if (isFaceCheck) {
    saveTempFormData(submitFormData, formKey.value);
    const res = await getFaceIdentifyUrl({ url: window.location.href });
    window.location.href = res.data;
    return false;
  }

  return true;
};

// Handle callback for operations that need to be completed on another page before submission
const handleCallBack = async () => {
  const backType = (router.currentRoute.value.query.backType || 0) as number;

  if (backType == 1) {
    const faceRes = await getFaceIdentifyInfo({ token: router.currentRoute.value.query.faceId });
    const tempData = getTempFormData(formKey.value);

    if (!tempData) {
      return false;
    }

    Object.keys(tempData.originalData).forEach(key => {
      if (key.includes("face_identify")) {
        tempData.originalData[key] = faceRes.data;
      }
    });

    const submitRes = await publicCreateFormResultRequest(tempData);
    removeTempFormData(formKey.value);
    handleSubmitSuccess(submitRes.data, tempData.originalData);
    return true;
  }

  return false;
};

const handleCheckEnter = () => {
  writeStatus.value = 1;
};

provide(SHOW_HEADER_USER_INFO_KEY, props.writeType != 2);
provide(SHOW_LANG_SWITCH_KEY, props.writeType != 2);
</script>

<style lang="scss" scoped>
.write-container {
  margin: 0;
  padding: 0;
  height: 100%;
  width: 100%;
  overflow-x: hidden;
  position: relative;
}

.title-icon-view {
  display: flex;
  align-items: center;
  align-content: center;
  justify-content: center;
  flex-direction: column;
  height: 100vh;
  width: 100%;
}

.result-wrapper {
  display: flex;
  align-items: center;
  justify-content: center;
  min-height: 80vh;
}

:deep(.el-result__title p) {
    color: var(--el-text-color-primary);
    font-size: var(--el-result-title-font-size);
    line-height: 1.3;
    margin: 0;
    font-size: 16px;
    font-weight: 500!important;
}

.icon-view {
  width: 59px;
  height: 59px;
  border-radius: 100px;
  background-color: #0076ff;
  display: flex;
  align-content: center;
  align-items: center;
  justify-content: center;
}

.success-icon {
  text-align: center;
  color: white;
  font-size: 30px;
}

.pwdinput-card {
  width: 350px;
  margin: 200px auto;
  min-height: 200px;
}

.fade-enter-active {
  transition: opacity 0.9s ease-in-out;
}

.fade-leave-active {
  transition: opacity 0.9s ease-in-out;
}

.fade-enter,
.fade-leave-to {
  opacity: 0;
}
</style>
